﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using XGame.Tools;
using XGame.Tools.PathFind;
using System.Collections;
using XGame.Tools.Graphics;

namespace XGame.Class
{
    public class Sprite
    {
        private AniPic aniPic;
        private int aniSpeed;
        private int aniCount;
        private Vector2 mouseClickVector;
        private Stack<Vector2> pathStack;
        private Vector2 nameVector;
        private Vector2 guildVector;
        private Vector2 affiliationVector;
        private SpriteFont font;

        public Utility.Direction Direction
        {
            get { return this.aniPic.Direction; }
            set { this.aniPic.Direction = value; }
        }
        private Vector2 speedVector;
        public Vector2 SpeedVector
        {
            get { return this.speedVector; }
            set { this.speedVector = value; }
        }
        private int speed;
        public int Speed
        {
            get { return this.speed; }
        }
        public AniPic.State State
        {
            get { return this.aniPic.CurrentState; }
            set { this.aniPic.CurrentState = value; }
        }
        private Vector2 positionVector;
        public Vector2 PositionVector
        {
            get { return this.positionVector; }
            set { this.positionVector = value; }
        }

        private string name;
        public string Name
        {
            get { return this.name; }
            set
            {
                if (!string.Equals(this.name, value))
                {
                    this.name = value;
                    this.nameVector = this.font.MeasureString(value);
                }
            }
        }
        //公会
        private string guild;
        public string Guild
        {
            get { return this.guild; }
            set
            {
                if (!string.Equals(this.guild, value))
                {
                    this.guild = value;
                    this.guildVector = this.font.MeasureString(value);
                }
            }
        }
        //门派
        private string affiliation;
        public string Affiliation
        {
            get { return this.affiliation; }
            set
            {
                if (!string.Equals(this.affiliation, value))
                {
                    this.affiliation = value;
                    this.affiliationVector = this.font.MeasureString(value);
                }
            }
        }

        public Sprite(AniPic aniPic, SpriteFont font, Vector2 firstPosition)
        {
            this.aniPic = aniPic;
            this.speed = 5;
            this.speedVector = Vector2.Zero;
            this.positionVector = firstPosition;
            this.aniSpeed = 150;
            this.aniCount = 0;
            this.font = font;
            this.Name = "Name";
            this.Guild = "Guild";
            this.Affiliation = "Affiliation";
        }

        public virtual void Update(bool isActive, GameTime gameTime, Map map)
        {
            this.aniCount += gameTime.ElapsedGameTime.Milliseconds;
            if (this.aniCount > this.aniSpeed)
            {
                this.aniCount -= this.aniSpeed;
                this.aniPic.Animate();
            }

            MouseState state = Mouse.GetState();
            if ((state.LeftButton == ButtonState.Pressed && isActive) &&
                !(state.X == this.mouseClickVector.X && state.Y == this.mouseClickVector.Y) &&
                !(state.X == this.positionVector.X && state.Y == this.positionVector.Y))
            {
                if (map.ExistPath(positionVector, new Vector2(state.X, state.Y)) == true)
                {
                    mouseClickVector = new Vector2(state.X, state.Y);
                    this.aniPic.CurrentState = AniPic.State.Run;
                    pathStack = null;
                }
            }
            if (this.aniPic.CurrentState == AniPic.State.Run)
            {
                //直线移动
                Vector2 distance = mouseClickVector - this.positionVector;
                if (distance == Vector2.Zero || distance.Length() / this.speed <= 1 || (pathStack != null && pathStack.Count == 0))
                {
                    //如果不是完全重合，需要得出速度矢量对方向作出调整，
                    if (distance != Vector2.Zero)
                    {
                        distance.Normalize();
                        this.speedVector = distance * this.speed;
                    }
                    //如果距离过小，直接移动过去。
                    this.positionVector = mouseClickVector;
                    this.aniPic.CurrentState = AniPic.State.Stand;
                    pathStack = null;
                }
                else
                {
                    distance.Normalize();
                    this.speedVector = distance * this.speed;
                    Vector2 tmp = this.positionVector + this.speedVector;
                    if (pathStack == null && map.IsObstacle(tmp.X, tmp.Y) == false)
                    {
                        //直线移动
                        this.positionVector = tmp;
                    }
                    else
                    {
                        if (pathStack == null)
                        {
                            pathStack = map.GetPathStack(positionVector, mouseClickVector);
                        }
                        if (pathStack.Peek() == this.positionVector)
                            pathStack.Pop();
                        //A*移动
                        this.speedVector = pathStack.Peek() - this.positionVector;
                        this.speedVector.Normalize();
                        this.speedVector *= this.speed;
                        this.positionVector += this.speedVector;
                        if (Vector2.Distance(this.positionVector, pathStack.Peek()) < this.speedVector.Length())
                        {
                            pathStack.Pop();
                        }
                    }
                }
                this.aniPic.Direction = Utility.GetDirectionByTan(Vector2.Zero, this.speedVector);
            }
        }

        public virtual void Draw(GameTime gameTime, DrawingContext drawingContext, SpriteFont font)
        {
            Texture2D pic = this.aniPic.Show();
            Vector2 offsetvector = new Vector2(pic.Width / 2, pic.Height);
            Vector2 topmid = new Vector2(this.positionVector.X + pic.Width / 2, this.positionVector.Y);
            Vector2 afflipos = topmid + new Vector2(-this.affiliationVector.X / 2, 3 - this.affiliationVector.Y);
            Vector2 guildpos = topmid + new Vector2(-this.guildVector.X / 2, 6 - this.affiliationVector.Y - this.guildVector.Y);
            Vector2 namepos = topmid + new Vector2(-this.nameVector.X / 2, 9 - this.affiliationVector.Y - this.guildVector.Y - this.nameVector.Y);
            drawingContext.DrawText(font, string.Format("X:{0},Y:{1}", this.positionVector.X, this.positionVector.Y), Vector2.Zero, Color.Yellow);
            drawingContext.DrawText(font, this.Name, namepos - offsetvector, Color.Yellow);
            drawingContext.DrawText(font, this.Guild, guildpos - offsetvector, Color.WhiteSmoke);
            drawingContext.DrawText(font, this.Affiliation, afflipos - offsetvector, Color.Pink);
            drawingContext.DrawTexture(pic, this.positionVector - offsetvector, Color.White);
            drawingContext.DrawPoints(new Vector2[] { this.positionVector }, Color.Red);
        }
    }
}
